<template>
  <a-modal class="image-cropper" v-model:visible="visible" title="编辑图片" :footer="false" @cancel="closeModal">
    <!-- 操作提示区域 -->
    <a-alert
      v-if="operationTips"
      :message="operationTips"
      :type="tipsType"
      show-icon
      style="margin-bottom: 16px"
      :closable="true"
      @close="operationTips = ''"
    />

    <vue-cropper
      ref="cropperRef"
      :img="imageUrl"
      :autoCrop="true"
      :fixedBox="false"
      :centerBox="true"
      :canMoveBox="true"
      :info="true"
      outputType="png"
    />
    <div style="margin-bottom: 16px" />

    <!-- 图片操作 -->
    <div class="image-cropper-actions">
      <a-space>
        <a-button @click="rotateLeft" :disabled="!canEdit">
          <template #icon><RotateLeftOutlined /></template>
          向左旋转
        </a-button>
        <a-button @click="rotateRight" :disabled="!canEdit">
          <template #icon><RotateRightOutlined /></template>
          向右旋转
        </a-button>
        <a-button @click="changeScale(1)" :disabled="!canEdit">
          <template #icon><ZoomInOutlined /></template>
          放大
        </a-button>
        <a-button @click="changeScale(-1)" :disabled="!canEdit">
          <template #icon><ZoomOutOutlined /></template>
          缩小
        </a-button>
        <a-button type="primary" :loading="loading" :disabled="!canEdit" @click="handleConfirm">
          <template #icon><CheckOutlined /></template>
          确认
        </a-button>
      </a-space>
    </div>

    <!-- 协同编辑操作 -->
    <div class="image-edit-actions" v-if="isTeamSpace">
      <a-space>
        <a-button v-if="editingUser" disabled>
          <template #icon><UserOutlined /></template>
          {{ editingUser.userName }}正在编辑
        </a-button>
        <a-button v-if="canEnterEdit" type="primary" ghost @click="enterEdit">
          <template #icon><EditOutlined /></template>
          进入编辑
        </a-button>
        <a-button v-if="canExitEdit" danger ghost @click="exitEdit">
          <template #icon><CloseOutlined /></template>
          退出编辑
        </a-button>
        <!-- 显示连接状态 -->
        <a-tag :color="isWebSocketConnected ? 'green' : 'red'" size="small">
          <template #icon><LinkOutlined /></template>
          {{ isWebSocketConnected ? '已连接' : '未连接' }}
        </a-tag>
      </a-space>
    </div>
  </a-modal>
</template>

<script setup lang="ts">
import { computed, onUnmounted, ref, watch, nextTick } from 'vue'
import { message } from 'ant-design-vue'
import {
  RotateLeftOutlined,
  RotateRightOutlined,
  ZoomInOutlined,
  ZoomOutOutlined,
  CheckOutlined,
  UserOutlined,
  EditOutlined,
  CloseOutlined,
  LinkOutlined
} from '@ant-design/icons-vue'
import { uploadPictureUsingPost } from '@/api/pictureController.ts'
import { useLoginUserStore } from '@/stores/useLoginUserStore.ts'
import PictureEditWebSocket from '@/utils/pictureEditWebSocket'
import { PICTURE_EDIT_MESSAGE_TYPE_ENUM, PICTURE_EDIT_ACTION_ENUM } from '@/constants/picture.ts'
import { SPACE_TYPE_ENUM } from '@/constants/space'

// 定义操作提示类型
type TipsType = 'info' | 'success' | 'warning' | 'error'

interface Props {
  imageUrl?: string
  picture?: API.PictureVO
  spaceId?: number
  space?: API.SpaceVO,
  onSuccess?: (newPicture: API.PictureVO) => void
}

const props = defineProps<Props>()
const cropperRef = ref()
const loading = ref<boolean>(false)
const visible = ref(false)
const isWebSocketConnected = ref(false)
const webSocketError = ref<string>()

// 新增：操作提示相关
const operationTips = ref<string>('')
const tipsType = ref<TipsType>('info')

// 打开弹窗
const openModal = () => {
  visible.value = true
  showOperationTips('info', '图片编辑窗口已打开')
}

defineExpose({
  openModal
})

// 显示操作提示
const showOperationTips = (type: TipsType, message: string, duration: number = 3) => {
  operationTips.value = message
  tipsType.value = type

  // 自动关闭提示
  setTimeout(() => {
    operationTips.value = ''
  }, duration * 1000)
}

// --------- 实时编辑 ---------
const loginUserStore = useLoginUserStore()
const loginUser = loginUserStore.loginUser
const editingUser = ref<API.UserVO>()
const isEditing = ref(false)
const knownUsers = ref<Record<string, string>>({})

const canEnterEdit = computed(() => {
  return !editingUser.value && isWebSocketConnected.value
})

const canExitEdit = computed(() => {
  return editingUser.value?.id === loginUser.id || isEditing.value
})

const canEdit = computed(() => {
  if (!isTeamSpace.value) {
    return true
  }
  if (isEditing.value) {
    return true
  }
  if (!editingUser.value) {
    return true
  }
  return editingUser.value?.id === loginUser.id
})

let websocket: PictureEditWebSocket | null

// 初始化WebSocket连接，绑定事件
const initWebsocket = async () => {
  // 重置状态
  isWebSocketConnected.value = false
  webSocketError.value = undefined
  showOperationTips('info', '正在建立协同编辑连接...')

  // 1. 确保pictureId存在
  const pictureId = props.picture?.id
  if (!pictureId) {
    const errorMsg = '缺少图片ID，无法建立协同编辑连接'
    showOperationTips('error', errorMsg)
    message.warning(errorMsg)
    return
  }

  // 2. 防止重复连接
  if (websocket) {
    if (isWebSocketConnected.value) {
      showOperationTips('info', '已处于连接状态')
      return
    } else {
      websocket.disconnect()
    }
  }

  try {
    await nextTick()

    // 3. 确定WebSocket基础地址（根据环境自动切换）
    const wsBaseUrl = import.meta.env.DEV
      ? import.meta.env.VITE_WS_DEV_URL || 'ws://localhost:8123/api'  // 开发环境
      : import.meta.env.VITE_WS_PROD_URL || 'ws://你的后端域名';  // 生产环境

    showOperationTips('info', `正在连接到: ${wsBaseUrl}`)

    // 4. 创建WebSocket实例并传入正确地址
    websocket = new PictureEditWebSocket(pictureId, wsBaseUrl)

    // 5. 监听连接状态
    websocket.on('open', () => {
      isWebSocketConnected.value = true
      webSocketError.value = undefined
      const successMsg = '协同编辑连接已建立，可以开始协同编辑'
      showOperationTips('success', successMsg)
      message.success(successMsg)
    })

    websocket.on('close', (code, reason) => {
      isWebSocketConnected.value = false
      console.log(`WebSocket关闭: 代码=${code}, 原因=${reason}`)

      // 根据关闭代码显示不同提示
      const closeReasons: Record<number, string> = {
        1000: '正常关闭',
        1006: '连接异常中断（可能是服务未启动或地址错误）',
        4001: '权限不足',
        4002: '图片不存在'
      }
      const reasonText = closeReasons[code] || `未知错误（代码: ${code}）`
      webSocketError.value = reasonText

      const errorMsg = `协同编辑连接已断开: ${reasonText}`
      showOperationTips('warning', errorMsg)
      if (visible.value) {
        message.warning(errorMsg)
      }
    })

    websocket.on('error', (error) => {
      isWebSocketConnected.value = false
      console.error('WebSocket错误详情:', error)
      const errorMsg = '连接失败，请检查服务是否可用'
      webSocketError.value = errorMsg
      showOperationTips('error', errorMsg)
      message.error(errorMsg)
    })

    // 6. 监听业务消息
    websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.INFO, (msg) => {
      console.log('收到通知消息：', msg)
      showOperationTips('info', msg.message)
      message.info(msg.message)
    })

    websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.ERROR, (msg) => {
      console.log('收到错误消息：', msg)
      showOperationTips('error', msg.message)
      message.error(msg.message)
    })

    websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.ENTER_EDIT, (msg) => {
      console.log('收到进入编辑状态消息：', msg)
      showOperationTips('info', msg.message)
      message.info(msg.message)
      editingUser.value = {
        id: msg.userId,
        userName: msg.userName
      }
      knownUsers.value[msg.userId] = msg.userName
      if (msg.userId === loginUser.id) {
        isEditing.value = true
        showOperationTips('success', '您已获得编辑权限，可以进行图片编辑操作')
      }
    })

    websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.EDIT_ACTION, (msg) => {
      console.log('收到编辑操作消息：', msg)
      if (msg.user?.userId !== loginUser.id) {
        const userName = msg.user?.userName || knownUsers.value[msg.user?.userId] || '未知用户'
        const actionText = formatActionText(msg.editAction)
        const infoMsg = `${userName}${actionText}`
        showOperationTips('info', infoMsg)
        message.info(infoMsg)

        // 执行对应的编辑操作
        switch (msg.editAction) {
          case PICTURE_EDIT_ACTION_ENUM.ROTATE_LEFT:
            cropperRef.value?.rotateLeft()
            break
          case PICTURE_EDIT_ACTION_ENUM.ROTATE_RIGHT:
            cropperRef.value?.rotateRight()
            break
          case PICTURE_EDIT_ACTION_ENUM.ZOOM_IN:
            cropperRef.value?.changeScale(1)
            break
          case PICTURE_EDIT_ACTION_ENUM.ZOOM_OUT:
            cropperRef.value?.changeScale(-1)
            break
        }
      }
    })

    websocket.on(PICTURE_EDIT_MESSAGE_TYPE_ENUM.EXIT_EDIT, (msg) => {
      console.log('收到退出编辑状态消息：', msg)
      showOperationTips('info', msg.message)
      message.info(msg.message)
      editingUser.value = undefined
      if (msg.userId === loginUser.id) {
        isEditing.value = false
        showOperationTips('info', '您已退出编辑状态，无法继续编辑')
      }
    })

    // 7. 建立连接
    websocket.connect()

  } catch (error) {
    console.error('初始化WebSocket失败:', error)
    const errorMsg = '无法初始化协同编辑功能'
    showOperationTips('error', errorMsg)
    message.error(errorMsg)
  }
}

// 格式化操作文本，使其更友好
const formatActionText = (action: string): string => {
  switch (action) {
    case PICTURE_EDIT_ACTION_ENUM.ROTATE_LEFT:
      return '将图片向左旋转'
    case PICTURE_EDIT_ACTION_ENUM.ROTATE_RIGHT:
      return '将图片向右旋转'
    case PICTURE_EDIT_ACTION_ENUM.ZOOM_IN:
      return '将图片放大'
    case PICTURE_EDIT_ACTION_ENUM.ZOOM_OUT:
      return '将图片缩小'
    default:
      return `执行了${action}操作`
  }
}

// 监听visible变化来初始化WebSocket
watch(visible, async (newVal) => {
  if (newVal) {
    await nextTick()
    if (isTeamSpace.value) {
      initWebsocket()
    } else {
      showOperationTips('info', '当前为个人空间，无需协同编辑连接')
    }
  } else {
    // 关闭时断开连接
    if (websocket) {
      if (isEditing.value) {
        websocket.sendMessage({
          type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.EXIT_EDIT,
          userId: loginUser.id,
          userName: loginUser.userName,
          message: `${loginUser.userName}已关闭编辑窗口`
        })
      }
      websocket.disconnect()
      websocket = null
    }
    editingUser.value = undefined
    isEditing.value = false
    knownUsers.value = {}
    isWebSocketConnected.value = false
    operationTips.value = ''
  }
}, { immediate: false })

// 监听picture变化
watch(() => props.picture?.id, (newId, oldId) => {
  if (newId && newId !== oldId && visible.value && isTeamSpace.value) {
    showOperationTips('info', '图片已更换，正在重新建立协同连接...')
    initWebsocket()
  }
})

onUnmounted(() => {
  if (websocket) {
    websocket.disconnect()
  }
  isWebSocketConnected.value = false
})

const closeModal = () => {
  visible.value = false
  showOperationTips('info', '图片编辑窗口已关闭')
}

const enterEdit = () => {
  if (websocket && isWebSocketConnected.value) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.ENTER_EDIT,
      userId: loginUser.id,
      userName: loginUser.userName,
      message: `${loginUser.userName}进入编辑状态`
    })
    editingUser.value = {
      id: loginUser.id,
      userName: loginUser.userName
    }
    knownUsers.value[loginUser.id] = loginUser.userName
    isEditing.value = true
    showOperationTips('info', '正在请求编辑权限...')
  } else {
    const warningMsg = '连接未建立，无法进入编辑'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
  }
}

const exitEdit = () => {
  if (websocket && isWebSocketConnected.value) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.EXIT_EDIT,
      userId: loginUser.id,
      userName: loginUser.userName,
      message: `${loginUser.userName}退出编辑状态`
    })
    editingUser.value = undefined
    isEditing.value = false
    showOperationTips('info', '已退出编辑状态')
  }
}

const editAction = (action: string) => {
  if (!isWebSocketConnected.value) {
    const warningMsg = '连接已断开，无法同步操作'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
    return
  }
  if (websocket && canEdit.value) {
    websocket.sendMessage({
      type: PICTURE_EDIT_MESSAGE_TYPE_ENUM.EDIT_ACTION,
      editAction: action,
      userId: loginUser.id,
      userName: loginUser.userName,
      message: `${loginUser.userName}执行了${action}操作`
    })
    showOperationTips('success', `已执行${formatActionText(action)}操作`)
  } else if (!canEdit.value) {
    const warningMsg = '暂无编辑权限，请先获取编辑权限'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
  }
}

const rotateLeft = () => {
  if (canEdit.value) {
    cropperRef.value?.rotateLeft()
    editAction(PICTURE_EDIT_ACTION_ENUM.ROTATE_LEFT)
  } else {
    const warningMsg = '暂无编辑权限，无法旋转图片'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
  }
}

const rotateRight = () => {
  if (canEdit.value) {
    cropperRef.value?.rotateRight()
    editAction(PICTURE_EDIT_ACTION_ENUM.ROTATE_RIGHT)
  } else {
    const warningMsg = '暂无编辑权限，无法旋转图片'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
  }
}

const changeScale = (num: number) => {
  if (canEdit.value) {
    cropperRef.value?.changeScale(num)
    if (num > 0) {
      editAction(PICTURE_EDIT_ACTION_ENUM.ZOOM_IN)
    } else {
      editAction(PICTURE_EDIT_ACTION_ENUM.ZOOM_OUT)
    }
  } else {
    const warningMsg = '暂无编辑权限，无法缩放图片'
    showOperationTips('warning', warningMsg)
    message.warning(warningMsg)
  }
}

const handleConfirm = () => {
  showOperationTips('info', '正在处理图片并上传...')
  cropperRef.value?.getCropBlob((blob: Blob) => {
    const fileName = (props.picture?.name || 'image') + '.png'
    const file = new File([blob], fileName, { type: blob.type })
    handleUpload({ file })
  })
}

const handleUpload = async ({ file }: any) => {
  loading.value = true
  try {
    const params: API.PictureUploadRequestDTO = props.picture ? { id: props.picture.id } : {}
    params.spaceId = props.spaceId
    const res = await uploadPictureUsingPost(params, {}, file)
    if (res.data.code === 0 && res.data.data) {
      const successMsg = '图片上传成功'
      showOperationTips('success', successMsg, 5)
      message.success(successMsg)
      props.onSuccess?.(res.data.data)
      closeModal()
    } else {
      const errorMsg = `图片上传失败，${res.data.message || '请重试'}`
      showOperationTips('error', errorMsg)
      message.error(errorMsg)
    }
  } catch (error) {
    const errorMsg = '图片上传失败，网络错误'
    showOperationTips('error', errorMsg)
    message.error(errorMsg)
  } finally {
    loading.value = false
  }
}

const isTeamSpace = computed(() => {
  return props.space?.spaceType === SPACE_TYPE_ENUM.TEAM
})
</script>

<style scoped>
.image-cropper {
  text-align: center;
}

.image-cropper .vue-cropper {
  height: 400px;
}

/* 连接状态标签样式 */
.image-edit-actions .ant-tag {
  margin-left: 8px;
}

/* 操作提示样式 */
.ant-alert {
  text-align: left;
}
</style>

